////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
//                      *** AvaMods Next Map Chooser ***
//
//   diamond-optic
//   AMXX Dev Team
//   mod version 0.6b
//   12.02.07
//
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
//
// Credit:
//
//	- AMXmodX Dev Team (Default MapChooser plugin)
//	- thedeagles3 & bmann_420 (Deagles' Map Management)
//
////////////////////////////////////////////////////////////////////////
//
// Info:
//	- Specifically modified for AvaMods
//
//	- extend choice is shown on top & bottom
//	- seperate extend step for avalanche
//	- seperate max step for hill
//	- colored menu
//	- various spk & hud messages
//	- cancel vote using amx_cancelmapvote
//	- Avalanche will always be #1 on list if current map is not avalanche
//	- certain vote slots are normal maps, others are custom maps (uses sperate configs)
//
////////////////////////////////////////////////////////////////////////
//
// Commands:
//
//	amx_cancelmapvote		//Cancel a next map vote
//
////////////////////////////////////////////////////////////////////////
//
// CVARs:
//
//	amx_extendmap_max "300"		//Max time limit to extend to
//	amx_extendmap_step "20"		//# of minutes to extend maps by each time
//	amx_extendmap_max_hill "30"	//Max time limit for hill classic to extend to
//	amx_extendmap_step_ava "30"	//# of minutes to extend avalanche each time
//
//////////////////////////////////////////////////////////////////////////
//
// Defines:
//
//	#define NORMAL_MAPS 10		//# OF MAPS IN MAPS.INI
//	#define CUSTOM_MAPS 9		//# OF MAPS IN MAPS_CUSTOM.INI
//	#define SELECTMAPS  5		//# OF TOTAL MAPS TO SHOW ON VOTE MENU
//	#define CUSTOM_VOTE 2		//# OF CUSTOM MAPS ON THE VOTE MENU
//
//	//Admin Level to use amx_cancelmapvote
//	#define CANCEL_ADMIN	ADMIN_LEVEL_A	
//
//	//Title of the next map vote menu
//	#define MENU_NAME "AvaMods - Vote for the next map"
//
//	//Chat text when a vote starts
//	#define TXT_STARTVOTE	"Alright fools, which map do you want next?"
//
//	//Chat text when a map is extended
//	//variables must be used and must stay in same order
//	//first variable (%s): current map name
//	//second variable (%.0f): how much longer its being extended
//	//third variable (%.0f): total timelimit on map including current extension
//	#define TXT_EXTEND	"Voting shit done. %s will be extended %.0f more minutes (total runtime: %.0fmins)"
//
//	//Chat text when a map has won
//	//variable must be used
//	//variable (%s): name of the map that won
//	#define TXT_NEXTMAP	"Voting shit done. The nextmap will be %s"
//
//	//Chat text when a player votes to extend
//	//both variables must be used and stay in the same order
//	//first variable (%s): player's name
//	//second variable (%d): how many votes for extend so far
//	#define TXT_VOTE_EXTEND	"%s voted to extend the current map (%d votes)"
//
//	//Chat text when a player votes for a map
//	//variables must be used and must stay in same order
//	//first variable (%s): player's name
//	//second variable (%s): map they voted for
//	//third variable (%s): number of votes for that map so far
//	#define TXT_VOTE_MAP	"%s voted for %s (%d votes)"
//
//	//Chat text when the map ends
//	//variables must be used and must stay in same order
//	//first variable (%s): current map name
//	//second variable (%s): next map name
//	#define TXT_MAPEND	"%s is finished, the nextmap will be %s"
//
//////////////////////////////////////////////////////////////////////////
//
// Change Log:
//
//	- 07.24.2006 Mod Version 0.1b
//		Fixed mistake with extend map parts
//
//	- 09.25.2006 Mod Version 0.1c
//		Removed showing current map in vote list
//
//	- 11.16.2006 Mod Version 0.2
//		Added command to cancel end of map vote
//
//	- 12.25.2006 Mod Version 0.3
//		added amxx 1.76c changes
//
//	- 02.10.2007 Mod Version 0.4
//		If the current map is not avalanche, avalanche will be #1 on the list
//
//	- 05.28.2007 Mod Version 0.5
//		Fixed a dumb typo :D
//		Various little tweaks here & there...
//		Added hud messages and vox for vote stuff
//		Removed 'modified' text from vote selections
//		Added some amx_nextmap custom stuff...
//		Added using 2 seperate configs (normal & custom maps)
//		Removed use of MapChooser language file
//		avalanche now has its own extend step cvar
//		hill classic now has its own max time cvar
//
//	- 11.05.2007 Version 0.6
//		** Began work on v1.0 release !!!! NOW 0.6 **
//
//		changed default cancel admin level (now is 't' flag)
//		adjusted placement of extended hud msg
//		changed my default map count
//		if no one votes, it restarts ava instead of ava <-> hill
//		attempt to make extend override switching if equal votes
//
//	- 12.02.2007 Version 0.6b (server 2 version)
//		If no votes it does ava <-> hill loop
//	
//
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////

#include <amxmodx>
#include <amxmisc>

////////////////////////////////////////////////////////////////////////

#define NORMAL_MAPS 22		//# OF MAPS IN MAPS.INI
#define CUSTOM_MAPS 13		//# OF MAPS IN MAPS_CUSTOM.INI
#define SELECTMAPS  4		//# OF TOTAL MAPS TO SHOW ON VOTE MENU
#define CUSTOM_VOTE 1		//# OF CUSTOM MAPS ON THE VOTE MENU

////////////////////////////////////////////////////////////////////////

#define CANCEL_ADMIN	ADMIN_LEVEL_B

////////////////////////////////////////////////////////////////////////

#define MENU_NAME "AvaMods - Vote for the next map"

////////////////////////////////////////////////////////////////////////

#define TXT_STARTVOTE	"Alright fools, which map do you want next?"
#define TXT_EXTEND	"Voting shit done. %s will be extended %.0f more minutes (total runtime: %.0fmins)"
#define TXT_NEXTMAP	"Voting shit done. The nextmap will be %s"
#define TXT_VOTE_EXTEND	"%s voted to extend the current map (%d votes)"
#define TXT_VOTE_MAP	"%s voted for %s (%d votes)"
#define TXT_MAPEND	"%s is finished, the nextmap will be %s"

////////////////////////////////////////////////////////////////////////

new g_mapName[NORMAL_MAPS+CUSTOM_MAPS][32]
new g_mapNums = 0
new g_custNums = 0

new g_nextName[SELECTMAPS]
new g_voteCount[SELECTMAPS + 2]
new g_mapVoteNum
new g_lastMap[32]

new g_coloredMenus
new bool:g_selected = false

new p_max, p_max2, p_step, p_step2, p_nextmap

public plugin_init()
{
	register_plugin("avamods mapchooser", "0.6b", "diamond-optic")
	
	register_cvar("avamods_mapchooser_stats", "0.6b", FCVAR_SERVER|FCVAR_SPONLY)
	
	register_dictionary("common.txt")
	register_dictionary("adminvote.txt")
	
	register_menucmd(register_menuid(MENU_NAME), (-1^(-1<<(SELECTMAPS+2))), "countVote")
	
	p_max = register_cvar("amx_extendmap_max", "300")
	p_step = register_cvar("amx_extendmap_step", "20")
	p_max2 = register_cvar("amx_extendmap_max_hill", "30")
	p_step2 = register_cvar("amx_extendmap_step_ava", "30")
	p_nextmap = register_cvar("amx_extendmap_nextmap", "www.AvaMods.com")
	
	register_concmd("amx_cancelmapvote", "cmdCancelVote", CANCEL_ADMIN, "- cancels end of map vote")

	get_localinfo("lastMap", g_lastMap, 31)
	set_localinfo("lastMap", "")

	new maps_ini_file[64], custom_ini_file[64], configs_dir[64]
	get_configsdir(configs_dir, 64);
	format(maps_ini_file, 64, "%s/maps.ini", configs_dir);
	format(custom_ini_file, 64, "%s/maps_custom.ini", configs_dir);
		
	if (!file_exists(maps_ini_file))
		get_cvar_string("mapcyclefile", maps_ini_file, 63)
		
	if (!file_exists(custom_ini_file))
		get_cvar_string("mapcyclefile", custom_ini_file, 63)
		
	if (loadSettings(maps_ini_file,custom_ini_file))
		set_task(30.0, "voteNextmap", 987456, "", 0, "b")  //15

	g_coloredMenus = colored_menus()
	
	
}

// Dont need to precache sounds for spk commands?
/*
public plugin_precache()
{
	precache_sound("gman/gman_choose1.wav")
	precache_sound("gman/gman_choose2.wav")
	precache_sound("barney/letsgo.wav")
	precache_sound("barney/waitin.wav")
}
*/

public plugin_cfg()
{
	new nextmap[32]
	get_pcvar_string(p_nextmap,nextmap,31)
	
	set_cvar_string("amx_nextmap", nextmap)
}

public checkVotes()
{
	new b = 0
	
	for (new a = 0; a < g_mapVoteNum; ++a)
		if (g_voteCount[b] < g_voteCount[a])
			b = a
	
	if (g_voteCount[SELECTMAPS] >= g_voteCount[b] && g_voteCount[SELECTMAPS] > g_voteCount[SELECTMAPS+1])
		{
		new mapname[32]
		get_mapname(mapname, 31)
		
		new Float:steptime
		
		if(equali(mapname, "dod_avalanche"))
			steptime = get_pcvar_float(p_step2)
		else
			steptime = get_pcvar_float(p_step)
			
		new Float:timelimit = (get_cvar_float("mp_timelimit") + steptime)
				
		set_cvar_float("mp_timelimit", timelimit)
		
		client_print(0, print_chat, TXT_EXTEND, mapname, steptime, timelimit)
		client_cmd(0,"spk ^"barney/(p98) waitin^"")
		
		set_hudmessage(222, 70,0, -1.0, 0.20, 0, 4.0, 8.0, 2.0, 2.0, 6)    
		show_hudmessage(0,"%s will be extended for another %.0f minutes^n(%d votes)",mapname,steptime,g_voteCount[SELECTMAPS]) 
		
		log_amx("Vote: Voting for the nextmap finished. %s will be extended %.0f more minutes (total runtime: %.0fmins)", mapname, steptime, timelimit)
		
		return
		}
	else if (g_voteCount[b] && g_voteCount[SELECTMAPS + 1] <= g_voteCount[b])
		{
		set_cvar_string("amx_nextmap", g_mapName[g_nextName[b]])
		
		new timeleft = get_timeleft() 
		
		set_hudmessage(0,152,255, -1.0, 0.20, 0, 4.0, 7.0, 2.1, 1.5, 6) 
		show_hudmessage(0,"%s wins with %d votes.^nMap will change in %d seconds",g_mapName[g_nextName[b]],g_voteCount[b],timeleft)
		}
	else
		{
		
		new mapname[32],nmap[32]
		get_mapname(mapname, 31)
			
		if(equali(mapname, "dod_avalanche"))
			format(nmap,31,"dod_hill_classic")
		else
			format(nmap,31,"dod_avalanche")
		
		//new nmap[32]
		//formatex(nmap,31,"dod_avalanche")
			
		set_cvar_string("amx_nextmap", nmap)
		
			
		new timeleft = get_timeleft() 
		
		set_hudmessage(0,152,255, -1.0, 0.22, 0, 4.0, 7.0, 2.1, 1.5, 6) 
		show_hudmessage(0,"no one voted! changing to %s in %d seconds",nmap,timeleft)
		}
		
	new smap[32]
	get_cvar_string("amx_nextmap",smap,31)
		
	client_print(0, print_chat, TXT_NEXTMAP, smap)
	client_cmd(0,"spk ^"barney/(p98) letsgo^"")
	        
	log_amx("Vote: Voting for the nextmap finished. The nextmap will be %s", smap)
}

public countVote(id, key)
{
	if(get_cvar_float("amx_vote_answers"))
		{
		new name[32]
		get_user_name(id, name, 31)
		
		if (key == SELECTMAPS)
			client_print(0, print_chat, TXT_VOTE_EXTEND, name, g_voteCount[key]+1)
		else if (key < SELECTMAPS)
			client_print(0, print_chat, TXT_VOTE_MAP, name, g_mapName[g_nextName[key]], g_voteCount[key]+1)
		}
	
	++g_voteCount[key]
	
	return PLUGIN_HANDLED
}

bool:isInMenu(id)
{
	for (new a = 0; a < g_mapVoteNum; ++a)
		if (id == g_nextName[a])
			return true
	return false
}

public voteNextmap()
{
	new timeleft = get_timeleft()
	
	if(timeleft < 1)
		{
		new nextmap[32], currentmap[32]
		get_cvar_string("amx_nextmap",nextmap,31)
		get_mapname(currentmap, 31)
		
		client_print(0, print_chat, TXT_MAPEND, currentmap, nextmap)
		client_cmd(0,"spk ^"barney/(p98) letsgo^"")	
		}
	
	if(timeleft > 126 && timeleft < 160)
		{
		set_hudmessage(0, 222,50, -1.0, 0.22, 1, 6.0, 6.0, 1.0, 1.0, 6)    
		show_hudmessage(0,"* next map vote will begin in 30 seconds *") 
		
		switch(random_num(0,1))
			{
			//more of a normal pitch
			case 0:	client_cmd(0,"spk ^"vox/(v60) _comma(e25) (p92) get (p95) red(e65) ninety(s48) (p91) to (p93) check(e20) (p91) use _comma(e7) (p91) bay(s18) mass(e45) (p93) cap(s55)^"")  
			//bit lower pitched
			case 1: client_cmd(0,"spk ^"vox/(v60) _comma(e25) (p86) get red(e65) ninety(s48) (p84) to (p86) check(e20) use _comma(e7) bay(s18) mass(e45) cap(s55)^"")
			}
		
		g_selected = false
		return
		}
		
	if (timeleft < 1 || timeleft > 126)
		{
		g_selected = false
		return
		}

	if (g_selected)
		return

	g_selected = true
	
	new menu[512], a, mkeys = (1<<SELECTMAPS + 1)
	new pos = format(menu, 511, g_coloredMenus ? "\yAvaMods - vote for the nextmap:\w^n^n" : "AvaMods - vote for the nextmap:^n^n")
	new dmax = (g_mapNums+g_custNums > SELECTMAPS) ? SELECTMAPS : g_mapNums+g_custNums
	
	g_voteCount[SELECTMAPS] = 0
	g_voteCount[SELECTMAPS + 1] = 0
	
	new mapname[32]
	get_mapname(mapname, 31)
	
	new Float:timelimit = get_cvar_float("mp_timelimit")
	
	if(equali(mapname, "dod_hill_classic"))
		{
		if (timelimit < get_pcvar_float(p_max2))
			{
			pos += format(menu[pos], 511, g_coloredMenus ? "\y%d. \r*EXTEND map %s^n" : "%d. *EXTEND map %s^n", SELECTMAPS + 1, mapname)
			mkeys |= (1<<SELECTMAPS)
			}
		}
	else
		{
		if (timelimit < get_pcvar_float(p_max))
			{
			pos += format(menu[pos], 511, g_coloredMenus ? "\y%d. \r*EXTEND map %s^n" : "%d. *EXTEND map %s^n", SELECTMAPS + 1, mapname)
			mkeys |= (1<<SELECTMAPS)
			}
		}
	
	menu[pos++] = '^n'
	
	for (g_mapVoteNum = 0; g_mapVoteNum < dmax; ++g_mapVoteNum)
	{
		if(g_mapVoteNum == 0 && !equali(mapname, "dod_avalanche"))
			{
			for(a = 0; a < g_mapNums;)
				{
				if(equali(g_mapName[a], "dod_avalanche"))
					break
				else
					a++
				}
			}
		else if(g_mapVoteNum < dmax-CUSTOM_VOTE)
			a = random_num(0, g_mapNums - 1)
		else //if(g_mapVoteNum >= dmax-CUSTOM_VOTE)
			a = random_num(g_mapNums, g_mapNums + g_custNums - 1)

			
		while (isInMenu(a))
			if (++a > g_mapNums+g_custNums) a = 0
		
		g_nextName[g_mapVoteNum] = a
		pos += format(menu[pos], 511, g_coloredMenus ? "\w%d. \d%s^n" : "%d. %s^n", g_mapVoteNum + 1, g_mapName[a])
		mkeys |= (1<<g_mapVoteNum)
		g_voteCount[g_mapVoteNum] = 0
	}
	
	menu[pos++] = '^n'

	if(equali(mapname, "dod_hill_classic"))
		{
		if(timelimit < get_pcvar_float(p_max2))
			{
			pos += format(menu[pos], 511, g_coloredMenus ? "\y%d. \r*EXTEND map %s^n" : "%d. *EXTEND map %s^n", SELECTMAPS + 1, mapname)
			mkeys |= (1<<SELECTMAPS)
			}
		}
	else
		{
		if(timelimit < get_pcvar_float(p_max))
			{
			pos += format(menu[pos], 511, g_coloredMenus ? "\y%d. \r*EXTEND map %s^n" : "%d. *EXTEND map %s^n", SELECTMAPS + 1, mapname)
			mkeys |= (1<<SELECTMAPS)
			}
		}
	
	menu[pos++] = '^n'

	//format(menu[pos], 511, g_coloredMenus ? "\w0. \yNone" : "0. None")

	show_menu(0, mkeys, menu, 25, MENU_NAME)
	set_task(29.0, "checkVotes", 99423781)
	client_print(0, print_chat, TXT_STARTVOTE)
	client_cmd(0, "spk ^"gman/(p85) gman_choose%d^"",random_num(1,2))
	//log_amx("Vote: Voting for the next map started")
}

loadSettings(filename[],customfile[])
{
	if (!file_exists(filename) || !file_exists(customfile))
		return 0

	new szText[32], custText[32]
	new a, pos = 0
	new b, line = 0
	new currentMap[32]
	
	get_mapname(currentMap, 31)
		
	while ((g_mapNums < NORMAL_MAPS) && read_file(filename, pos++, szText, 31, a))
	{
		if (szText[0] != ';' && parse(szText, g_mapName[g_mapNums], 31) && is_map_valid(g_mapName[g_mapNums]) 
			&& !equali(g_mapName[g_mapNums], currentMap))
			++g_mapNums
	}
	
	while ((g_custNums < CUSTOM_MAPS) && read_file(customfile, line++, custText, 31, b))
	{
		new g_curTotal = g_mapNums+g_custNums
		
		if (custText[0] != ';' && parse(custText, g_mapName[g_curTotal], 31) && is_map_valid(g_mapName[g_curTotal]) 
			&& !equali(g_mapName[g_curTotal], currentMap))
			++g_custNums
	}
		
	return g_mapNums+g_custNums
}

public cmdCancelVote(id, level, cid)
{
	if (!cmd_access(id, level, cid, 0))
		return PLUGIN_HANDLED

	if (task_exists(99423781, 1))
		{
		new authid[32], name[32]
		
		get_user_authid(id, authid, 31)
		get_user_name(id, name, 31)
		
		log_amx("NextMap Vote: %s<%d><%s> cancelled nextmap vote session/results", name, get_user_userid(id), authid)
		
		new players[32], pnum, lTag[16], activity = get_cvar_num("amx_show_activity")
		get_players(players, pnum, "c")
		
		for (new i = 0; i < pnum;i ++)
			{
			format(lTag, 15, "%L", players[i], is_user_admin(id) ? "ADMIN" : "PLAYER")
			switch (activity)
				{
				case 1: client_print(players[i], print_chat, "%L", LANG_PLAYER, "ADMIN_CANC_VOTE_1", lTag)
				case 2: client_print(players[i], print_chat, "%L", LANG_PLAYER, "ADMIN_CANC_VOTE_2", lTag, name)
				}
			}
		
		console_print(id, "%L", id, "VOTING_CANC")
		client_print(id,print_chat,"%L",LANG_PLAYER,"VOTING_CANC")
		remove_task(99423781, 1)
		}
	else
		console_print(id, "%L", id, "NO_VOTE_CANC")

	return PLUGIN_HANDLED
}

public plugin_end()
{
	new current_map[32]

	get_mapname(current_map, 31)
	set_localinfo("lastMap", current_map)
	
	new nextmap[32],nextmap_cvar[32]
	get_cvar_string("amx_nextmap",nextmap,31)
	get_pcvar_string(p_nextmap,nextmap_cvar,31)
	
	if(equal(nextmap,nextmap_cvar))
		set_cvar_string("amx_nextmap", "dod_avalanche")
	
}
